package com.authine.cloudpivot.ext.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.PlatformConst;
import com.authine.cloudpivot.ext.constants.WebConstants;
import com.authine.cloudpivot.ext.dto.GatewayResponse;
import com.authine.cloudpivot.ext.dto.OrderTraceDto;
import com.authine.cloudpivot.ext.dto.OrderVendorDto;
import com.authine.cloudpivot.ext.dto.OrderVendorGoodsDto;
import com.authine.cloudpivot.ext.dto.api.OrderDeliverVO;
import com.authine.cloudpivot.ext.dto.api.TempOrderReceipt;
import com.authine.cloudpivot.ext.dto.system.OrganizationDto;
import com.authine.cloudpivot.ext.dto.system.UserDto;
import com.authine.cloudpivot.ext.enums.OrderGoodsStatusV1Enum;
import com.authine.cloudpivot.ext.enums.order.*;
import com.authine.cloudpivot.ext.eum.VendorOrderStatusV1Enum;
import com.authine.cloudpivot.ext.service.DockFinanceService;
import com.authine.cloudpivot.ext.service.OrderService;
import com.authine.cloudpivot.ext.service.OrderVendorBaseV1Service;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.cloudpivot.ext.utils.system.OrgUtils;
import com.authine.cloudpivot.ext.utils.system.SessionUser;
import com.authine.cloudpivot.ext.vo.OrderGoodsSimple;
import com.authine.cloudpivot.ext.vo.OrderGoodsV1VO;
import com.authine.common.json.JsonUtils;
import com.authine.mvp.app.launcher.common.TableHelper;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.utils.JsonParseObject;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: liwei
 * @DateTime: 2021/9/4
 * @Description: TODO
 */
@Slf4j
public class OrderVendorBaseV1ServiceImpl implements OrderVendorBaseV1Service {
    private NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);
    private final TableHelper tableHelper = ApplicationContextUtils.getBean(TableHelper.class);
    private OrderService orderService = new OrderServiceImpl();
    private DockFinanceService dockFinanceService = new DockFinanceServiceImpl();

    @Override
    public BOList vendorOrderByPageContainVendor(OrderVendorDto dto) {

        log.info("------------------------分页查询供应商订单 vendorOrderByPageContainVendor Param：{}------------------------", JsonUtils.toJson(dto));
        if (null == dto.getPageIndex()) {
            dto.setPageIndex(WebConstants.DEF_PAGE);
        }

        if (null == dto.getPageSize() || dto.getPageSize() > 100) {
            dto.setPageSize(WebConstants.DEF_SIZE);
        }

        String vendorTableName = getTableName(ModelConst.T_ORDER_VENDOR);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
//        select v.*,c.ero_po,c.receiver,c.phone,c.postal,c.address
        listSql.append("SELECT * FROM " + vendorTableName + " v WHERE v.deleted ='0' ");
        countSql.append("SELECT COUNT(*) FROM " + vendorTableName + " v WHERE v.deleted ='0' ");
        //拼接参数
        //供应商订单序号
        if (!CollectionUtils.isEmpty(dto.getIds())) {
            whereSql.append(" AND v.id IN (:ids) ");
            parameter.put("ids", dto.getIds());
        }
        //客户订单商品序号
        if (!CollectionUtils.isEmpty(dto.getOrderCustomerIdList())) {
            whereSql.append(" AND v.order_customer_id IN (:orderCustomerIds) ");
            parameter.put("orderCustomerIds", dto.getOrderCustomerIdList());
        }
        //供应商id
        if (!CollectionUtils.isEmpty(dto.getVendorIdList())) {
            whereSql.append(" AND JSON_UNQUOTE(v.organization_id ->'$.id') IN (:vendorIdList) ");
            parameter.put("vendorIdList", dto.getVendorIdList());
        }
        //orderVendorStatus
        // 新老状态转换
        if (null != dto.getVendorOrderStatusV1Enum()) {
            VendorOrderStatusV1Enum vendorOrderStatusV1Enum = dto.getVendorOrderStatusV1Enum();

            if (vendorOrderStatusV1Enum == VendorOrderStatusV1Enum.NEW) {
               // 新建 =》未付款
                whereSql.append(" AND v.order_vendor_status = :orderVendorStatus ");
                parameter.put("orderVendorStatus", OrderVendorStatusEnum.UpcomingPayment.name());
            }
            if (vendorOrderStatusV1Enum == VendorOrderStatusV1Enum.ORDERS) {
               // 待接单 =》未接单
                whereSql.append(" AND v.order_vendor_status = :orderVendorStatus ");
                parameter.put("orderVendorStatus", OrderVendorStatusEnum.UpcomingConfirm.name());
            }
            if (vendorOrderStatusV1Enum == VendorOrderStatusV1Enum.TRANSACTION) {
                //交易中 =》未发货 | 已发货
                whereSql.append(" AND v.order_vendor_status = :orderVendorStatus ");
                parameter.put("orderVendorStatus", Lists.newArrayList(OrderVendorStatusEnum.UpcomingDelivery.name(),OrderVendorStatusEnum.DoneDelivery.name()));
            }
            if (vendorOrderStatusV1Enum == VendorOrderStatusV1Enum.CANCEL) {
                //已关闭 =》已关闭 & 售后状态=已售后
                whereSql.append(" AND v.order_vendor_status = :orderVendorStatus AND v.after_sale = :afterSale");
                parameter.put("orderVendorStatus", OrderVendorStatusEnum.Closed.name());
                parameter.put("afterSale", PlatformConst.DONE_AFTER_SALE);
            }
            if (vendorOrderStatusV1Enum == VendorOrderStatusV1Enum.DONE) {
                //已完成 =》已完成
                whereSql.append(" AND v.order_vendor_status = :orderVendorStatus ");
                parameter.put("orderVendorStatus", OrderVendorStatusEnum.Done.name());
            }
        }

        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" ORDER BY v.id desc");
        listSql.append(" LIMIT " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------分页查询供应商订单 vendorOrderByPageContainVendor listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        log.info("------------------------分页查询供应商订单 vendorOrderByPageContainVendor whereSql：{}------------------------parameter：{}", whereSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_VENDOR);
        return bOList;
    }

    @Override
    public BOList listOrderVendorGoodsContainMemberIds(OrderVendorGoodsDto dto) {
        log.info("------------------------客户分页查询订单商品 listOrderVendorGoodsContainMemberIds Param：{}------------------------", JsonUtils.toJson(dto));

        if (null == dto.getPageIndex()) {
            dto.setPageIndex(WebConstants.DEF_PAGE);
        }

        if (null == dto.getPageSize() || dto.getPageSize() > 100) {
            dto.setPageSize(WebConstants.DEF_SIZE);
        }

        String vendorGoodsTableName = getTableName(ModelConst.T_ORDER_VENDOR_GOODS);
        String customerTableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
        String vendorTableName = getTableName(ModelConst.T_ORDER_VENDOR);
        String goodsReturnsTableName = getTableName(ModelConst.T_ORDER_GOODS_RETURNS);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("SELECT * FROM " + vendorGoodsTableName + " cg ");
        listSql.append(" LEFT JOIN " + customerTableName + " c ON cg.order_customer_id = c.id ");
        listSql.append(" LEFT JOIN " + vendorTableName + " v ON cg.order_vendor_id = v.id WHERE cg.deleted ='0' ");
        countSql.append("SELECT COUNT(*) FROM " + vendorGoodsTableName + " cg ");
        countSql.append(" LEFT JOIN " + customerTableName + " c ON cg.order_customer_id = c.id ");
        countSql.append(" LEFT JOIN " + vendorTableName + " v ON cg.order_vendor_id = v.id WHERE cg.deleted ='0' ");

        //拼接参数
        if (!CollectionUtils.isEmpty(dto.getIds())) {
            whereSql.append(" AND cg.id in (:ids) ");
            parameter.put("ids", dto.getIds());
        }

        if (!CollectionUtils.isEmpty(dto.getOrderCustomerIds())) {
            whereSql.append(" AND cg.order_customer_id in (:orderCustomerIds) ");
            parameter.put("orderCustomerIds", dto.getOrderCustomerIds());
        }

        if (!CollectionUtils.isEmpty(dto.getOrderVendorIds())) {
            whereSql.append(" AND cg.order_vendor_id in (:orderVendorIds) ");
            parameter.put("orderVendorIds", dto.getOrderVendorIds());
        }

        if (StringUtils.isNotBlank(dto.getBrand())) {
            whereSql.append(" AND cg.brand LIKE :brand ");
            parameter.put("brand", "%" + dto.getBrand() + "%");
        }
        if (StringUtils.isNotBlank(dto.getName())) {
            whereSql.append(" AND cg.`name` LIKE :name ");
            parameter.put("name", "%" + dto.getName() + "%");
        }
        if (StringUtils.isNotBlank(dto.getModel())) {
            whereSql.append(" AND cg.model LIKE :model ");
            parameter.put("model", "%" + dto.getModel() + "%");
        }
        if (StringUtils.isNotBlank(dto.getSpec())) {
            whereSql.append(" AND cg.spec LIKE :spec ");
            parameter.put("spec", "%" + dto.getSpec() + "%");
        }

        //todo 权限问题
        //todo 新老状态转换
        if (null != dto.getOrderGoodsStatusV1Enum()) {
            OrderGoodsStatusV1Enum orderGoodsStatusV1Enum = dto.getOrderGoodsStatusV1Enum();

            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.NEW) {
                //新建 ==》未付款 & label：审批中
                //label
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status AND c.label LIKE '%:label%' ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.UpcomingPayment.name());
                parameter.put("label", OrderApproveStatusEnum.APPROVING.id);

            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.SUBMIT) {
                //待付款 =》未付款 & label!=审批中
                // label
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status AND c.label NOT LIKE '%:label%' OR c.label IS NULL ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.UpcomingPayment.name());
                parameter.put("label", OrderApproveStatusEnum.APPROVING.id);
            }

            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.PAYED) {
                // 待出库（待发货） =》未接单
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.UpcomingConfirm.name());
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.PACKAGING) {
                //待发货（出库中） =》未发货 & 已发货数量 = 0
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status AND cg.quantity_shipped = '0' ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.UpcomingDelivery.name());
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.DELIVERED) {
                //待收货（已发货） =》已发货
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.DoneDelivery.name());
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.TO_RETURN) {
                // 待退货 =》label：待退货（客户退货）
                // label
                whereSql.append(" AND cg.label LIKE :goods_label ");
                parameter.put("goods_label", OrderApproveStatusEnum.TO_RETURN.id);
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.RETURNING) {
                // 退货中 =》label：退货中（供应商审批中）
                // label
                whereSql.append(" AND cg.label LIKE :goods_label ");
                parameter.put("goods_label", OrderApproveStatusEnum.RETURNING.id);
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.REFUNDING) {
                // 退款中 =》label：退款中（供应商审批中）
                //  label
                whereSql.append(" AND cg.label LIKE :goods_label ");
                parameter.put("goods_label", OrderApproveStatusEnum.REFUNDING.id);
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.RETIRED) {
                // 已退货 =》label：已退货（供应商收货）
                // label
                whereSql.append(" AND cg.label LIKE :goods_label ");
                parameter.put("goods_label", OrderApproveStatusEnum.RETIRED.id);
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.DONE) {
                //已完成 =》已完成
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.Done.name());
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.CLOSED) {
                //已关闭 =》已关闭& 退款退货数量=0
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status AND ( SELECT count(*) FROM "+goodsReturnsTableName+" odr WHERE odr.`order_goods_returns_status` not in ( :goodsReturnsStatusList ) AND odr.order_customer_goods_id = cg.id ) = '0' ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.Closed.name());
                parameter.put("goodsReturnsStatusList", Lists.newArrayList(OrderGoodsReturnsStatusEnum.Done.name(),OrderGoodsReturnsStatusEnum.Closed.name()));
            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.REFUND_APPLICATION) {
                //退款申请中 =》label：退款申请中（平台审批中）
                // label
                whereSql.append(" AND cg.label LIKE :goods_label ");
                parameter.put("goods_label", OrderApproveStatusEnum.REFUND_APPLICATION.id);

            }
            if (orderGoodsStatusV1Enum == OrderGoodsStatusV1Enum.RETURNED) {
                //已退款 = 》已关闭 & 退款退货数量=商品总数量
                whereSql.append(" AND cg.order_vendor_goods_status = :order_vendor_goods_status AND ( SELECT SUM(odr.quantity) FROM "+goodsReturnsTableName+" odr WHERE odr.`order_goods_returns_status`  = :goodsReturnsStatus AND odr.order_customer_goods_id = cg.id ) = cg.quantity ");
                parameter.put("order_vendor_goods_status", OrderGoodsStatusEnum.Closed.name());
                parameter.put("goodsReturnsStatus", OrderGoodsReturnsStatusEnum.Done.name());
            }
        }

        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" ORDER BY cg.id DESC");
        listSql.append(" LIMIT " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------客户分页查询订单商品 listOrderVendorGoodsContainMemberIds listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        log.info("------------------------客户分页查询订单商品 listOrderVendorGoodsContainMemberIds whereSql：{}------------------------parameter：{}", whereSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);

        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_CUSTOMER_GOODS);
        return bOList;

    }

    @Override
    public List<OrderGoodsV1VO> transferOrderVendorGoodsV1VOList(BOList boList) {

        if (null == boList || 0 == boList.getTotal() || null == boList.getData() ){
            return null;
        }

        List<String> relationIdList = boList.getData().stream().map(e -> String.valueOf(e.get("relation_id"))).collect(Collectors.toList());
        List<String> orderVendorIdList = boList.getData().stream().map(e -> String.valueOf(e.get("order_vendor_id"))).collect(Collectors.toList());

        List<Map<String, Object>> vendorOrderList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*").in("id", orderVendorIdList).queryForList();
        Assert.isTrue(!CollectionUtils.isEmpty(vendorOrderList), "查询客户订单商品信息 不能为空");

        List<Map<String, Object>> goodsRelationList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RELATION).selectField("*").in("id", relationIdList).queryForList();

        Map<String, Map<String, Object>> relationMap = null;
        if(!CollectionUtils.isEmpty(goodsRelationList)){
            relationMap = goodsRelationList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

        }
        Map<String, Map<String, Object>> vendorOderMap = vendorOrderList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

        List<OrderGoodsV1VO> orderGoodsV1VOList = new LinkedList<>();

        for (Map<String, Object> orderVendorGoods : boList.getData()) {

            Map<String, Object> relation = null == relationMap?null:relationMap.getOrDefault(String.valueOf(orderVendorGoods.get("relation_id")), null);
            Map<String, Object> vendorOder = vendorOderMap.getOrDefault(String.valueOf(orderVendorGoods.get("order_customer_id")), null);

            Map<String, Object> inquiry = null;
            if (null != relation) {
                //询价
                String inquiryId = String.valueOf(relation.get("inquiry_id"));
                inquiry = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY).selectField("*").eq("id", inquiryId).queryForMap();
            }

            //报价
            Map<String, Object> quotationGoods = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS).selectField("*").eq("id", orderVendorGoods.get("goods_id")).queryForMap();


            OrderGoodsV1VO orderGoodsV1VO = OrderGoodsV1VO.of().setOrderGoodsId(String.valueOf(orderVendorGoods.get("id")))
                    .setClientOrderGoodsId(String.valueOf(orderVendorGoods.get("client_order_goods_id")))
                    .setCustomerOrderId(String.valueOf(orderVendorGoods.get("order_customer_id")))
                    .setVendorOrderId(String.valueOf(orderVendorGoods.get("order_vendor_id")))
                    .setVendorName(String.valueOf(orderVendorGoods.get("vendor_organization_name")))
                    .setName(String.valueOf(orderVendorGoods.get("name")))
                    .setBrand(String.valueOf(orderVendorGoods.get("brand")))
                    .setModel(String.valueOf(orderVendorGoods.get("model")))
                    .setSpec(String.valueOf(orderVendorGoods.get("spec")))
                    .setSku(String.valueOf(orderVendorGoods.get("sku")))
                    .setBarCode(String.valueOf(orderVendorGoods.get("bar_code")))
                    .setUnspsc(String.valueOf(orderVendorGoods.get("unspsc")))
                    .setGoldenTax(String.valueOf(orderVendorGoods.get("golden_tax")))
                    .setImages(String.valueOf(orderVendorGoods.get("images")))
                    .setDescription(String.valueOf(orderVendorGoods.get("description")))
                    .setTechnical(String.valueOf(orderVendorGoods.get("technical")))
                    .setPackaging(String.valueOf(orderVendorGoods.get("packaging")))
                    .setMemo(String.valueOf(orderVendorGoods.get("memo")))
                    .setUnit(String.valueOf(orderVendorGoods.get("unit")))
                    .setPackageUnit(String.valueOf(orderVendorGoods.get("package_unit")))
                    .setNum(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("quantity")))
                    .setPackageNum(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("package_quantity")))
                    .setDelivery(BigDecimalUtils.bigDecimalToInteger(orderVendorGoods.get("delivery")))
                    .setTaxRate(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("tax_rate")))
                    .setTaxRateFreight(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("freight_rate")))
                    .setPretaxPrice(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("pretax_price")))
                    .setPrice(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("price")))
                    .setPretaxFreight(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("pretax_freight")))
                    .setFreight(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("freight")))
                    .setPretaxTotal(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("pretax_total")))
                    .setTotal(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("total")))
                    .setPretaxAmount(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("pretax_amount")))
                    .setAmount(BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("amount")))
                    .setStatus(String.valueOf(orderVendorGoods.get("order_vendor_goods_status")))
                    .setAttachment(String.valueOf(orderVendorGoods.get("attachment")))
                    .setOrderType(null == vendorOder ?null :String.valueOf(vendorOder.get("source")))
                    .setCustomerOrgName(String.valueOf(orderVendorGoods.get("customer_organization_name")))
                    .setMemberName(null == vendorOder ?null :String.valueOf(vendorOder.get("actual_order"))) //实际下单人？
                    .setTime(null == vendorOder ?null :Utils.strToDate(String.valueOf(vendorOder.get("createdTime"))))
                    .setClarifyTips(quotationGoods == null ? null : String.valueOf(quotationGoods.get("clarify_tips")))
                    .setCategory(String.valueOf(orderVendorGoods.get("category")))
                    .setRemarkMessages(quotationGoods == null ? null : String.valueOf(quotationGoods.get("remark_message")))
                    .setQuotationGoodsId(String.valueOf(orderVendorGoods.get("goods_id")))
                    .setDemandDeptName(inquiry == null ? null : String.valueOf(inquiry.get("department_name")))
                    .setInquiryMemberName(inquiry == null ? null : String.valueOf(inquiry.get("member_name")));

            orderGoodsV1VOList.add(orderGoodsV1VO);
        }

        return orderGoodsV1VOList;
    }

    @Override
    public String verifyOrderDeliverVO(List<OrderDeliverVO> orderDeliverVOS) {

        StringBuilder st = new StringBuilder();
        for (OrderDeliverVO orderDeliverVO : orderDeliverVOS) {

            if (StringUtils.isBlank(orderDeliverVO.getOrderGoodsId())) {
                st.append("订单商品ID 不能为空,\n");
            }

            if (null == orderDeliverVO.getNum() || orderDeliverVO.getNum().compareTo(BigDecimal.ZERO) < 1) {
                st.append("发货数量 不能为空,\n");
            }

            if (StringUtils.isBlank(orderDeliverVO.getWaybill())) {
                st.append("物流单号 不能为空,\n");
            }

            if (StringUtils.isBlank(orderDeliverVO.getLogistics())) {
                st.append("物流公司 不能为空,\n");
            }

            if (st.length() > 0) {
                return st.toString();
            }
        }
        return null;
    }

    @Override
    public List<String> getCloudDeliverGoods(List<String> virtualVendorGoodsIds) {

        List<String> goodsIds = new ArrayList<>();

        String memberPurchaseOrder = JdbcTemplateUtils.getTableName(ModelConst.T_MEMBER_PURCHASE_ORDER,AppConst.ZHUANCAI);
        String memberPurchaseOrderGoods = JdbcTemplateUtils.getTableName(ModelConst.T_MEMBER_PURCHASE_ORDER_GOODS,AppConst.ZHUANCAI);
        String transferVendor = JdbcTemplateUtils.getTableName(ModelConst.T_TRANSFER_VENDOR,AppConst.ZHUANCAI);
        String transferVendorGoods = JdbcTemplateUtils.getTableName(ModelConst.T_TRANSFER_ORDER_GOODS,AppConst.ZHUANCAI);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        listSql.append("SELECT GROUP_CONCAT( DISTINCT t.cloud_order_goods_id) AS cloud_order_goods_id  FROM " + memberPurchaseOrderGoods + " AS g ");
        listSql.append(" LEFT JOIN " + memberPurchaseOrder + " AS m ON m.id = g.member_purchase_order_id ");
        listSql.append(" LEFT JOIN " + transferVendorGoods + " AS t ON t.id = g.transfer_order_goods_id ");
        listSql.append(" LEFT JOIN " + transferVendor + " AS o ON o.id = t.transfer_order_id ");
        listSql.append(" WHERE g.deleted = FALSE AND o.order_type IS NULL AND m.deleted = FALSE AND m.is_rp <> TRUE AND m.member_purchase_order_status IN ( 2, 3, 4 ) AND t.cloud_order_goods_id IN ( :virtualVendorGoodsIds ) GROUP BY g.transfer_order_goods_id ");

        parameter.put("virtualVendorGoodsIds",virtualVendorGoodsIds);
        log.info("------------------------获取虚拟订单数据 getCloudDeliverGoods listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);

        if (!CollectionUtils.isEmpty(resultList)) {
            List<String> ids = new ArrayList<>();
            for (Map<String, Object> map : resultList) {
                ids.add(String.valueOf(map.get("cloud_order_goods_id")));
            }

            for (int i = 0; i < virtualVendorGoodsIds.size(); i++) {
                if (!ids.contains(virtualVendorGoodsIds.get(i))) {
                    goodsIds.add(virtualVendorGoodsIds.get(i));
                }
            }
        }
        return goodsIds;
    }

    /**
     * 获取可发货数量，可发数量=可退数量-已发数量+已退货数量
     *
     * @param vendorOrderGoodsList 订单商品列表
     * @return key=订单商品ID，value=可发货数量
     */
    @Override
    public Map<String, BigDecimal> getDeliverableQuantity(List<Map<String, Object>> vendorOrderGoodsList) {

        Map<String, BigDecimal> results = new HashMap<>();
        if (!CollectionUtils.isEmpty(vendorOrderGoodsList)) {

            List<String> orderGoodsIds = vendorOrderGoodsList.stream().map(e->String.valueOf(e.get("id"))).collect(Collectors.toList());

            // 退货的数据 t_order_goods_returns
            List<Map<String, Object>> refundList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RETURNS).selectField("*").in("order_vendor_goods_id", orderGoodsIds).queryForList();
            refundList = null == refundList ? Collections.emptyList() : refundList;

            Map<String, List<Map<String, Object>>> refundListMap = refundList.stream().collect(Collectors.groupingBy(e -> String.valueOf(e.get("order_vendor_goods_id"))));

            // 物流数据
            List<Map<String, Object>> traceList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_TRACE).selectField("*").eq("type", TraceTypeEnum.ShippingLogistics.name()).in("order_vendor_goods_id", orderGoodsIds).queryForList();
            traceList = null == traceList ? Collections.emptyList() : traceList;

            Map<String, List<Map<String, Object>>> traceListMap = traceList.stream().collect(Collectors.groupingBy(e -> String.valueOf(e.get("order_vendor_goods_id"))));

            for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {
                String id = String.valueOf(vendorOrderGoods.get("id"));

                BigDecimal doneRefundQuantity = BigDecimal.ZERO;
                if (!CollectionUtils.isEmpty(refundListMap)) {
                    for (Map<String, Object> refund : refundListMap.get(id)) {
                        doneRefundQuantity = doneRefundQuantity.add(BigDecimalUtils.integerToBigDecimal(refund.get("quantity")));
                    }
                }

                BigDecimal doneTransportQuantity = BigDecimal.ZERO;
                if (!CollectionUtils.isEmpty(traceListMap)) {
                    for (Map<String, Object> trace : traceListMap.get(id)) {
                        doneTransportQuantity = doneTransportQuantity.add(BigDecimalUtils.integerToBigDecimal(trace.get("quantity")));
                    }
                }
                //可发数量=可退数量-已发数量+已退货数量
                BigDecimal quantity = BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("quantity"));
                BigDecimal returnedNum = BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("returned_num"));
                BigDecimal canRefundQuantity = quantity.subtract(doneRefundQuantity);

                BigDecimal canTransportQuantity = canRefundQuantity.subtract(doneTransportQuantity).add(returnedNum);
                results.put(id, canTransportQuantity);
            }
        }
        return results;
    }

    /**
     * 供应商发货
     * @param orderDeliverVOS
     * @param sessionUser
     * @return
     */
    @Override
    public TempOrderReceipt deliver(List<OrderDeliverVO> orderDeliverVOS, SessionUser sessionUser) {

        List<String> orderGoodIds = orderDeliverVOS.stream().map(OrderDeliverVO::getOrderGoodsId).collect(Collectors.toList());

        //查询 供应商订单商品
        List<Map<String, Object>> vendorOrderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*").in("id", orderGoodIds).queryForList();
        Assert.isTrue(!CollectionUtils.isEmpty(vendorOrderGoodsList), " 未获取到需要发货的订单商品 ");

        // 供应商id
        List<String> vendorOrgIds = new ArrayList<>();
        Map<String,String> vendorGoodsInfo = new HashMap<>();
        for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {
            if (null != vendorOrderGoods.get("vendor_organization_id")) {
                List<SelectorFormat> selectorFormats = JsonParseObject.parseObject((String) vendorOrderGoods.get("vendor_organization_id"), SelectorFormat.class);
                if (!CollectionUtils.isEmpty(selectorFormats)) vendorOrgIds.add(selectorFormats.get(0).getId()) ;
                vendorGoodsInfo.put(selectorFormats.get(0).getId(),(String) vendorOrderGoods.get("id"));
            }
        }
        Assert.isTrue(!CollectionUtils.isEmpty(vendorOrgIds), " 供应商组织ID不能为空 ");

        //获取组织
        List<OrganizationDto> organizationDtoList = OrgUtils.getOrgListByOrgIds(vendorOrgIds);
        Assert.isTrue(!CollectionUtils.isEmpty(organizationDtoList), " 未获取到组织信息 ");

        List<OrganizationDto> virtualOrganizationDtoList = organizationDtoList.stream().filter(e -> e.getVirtual()).collect(Collectors.toList());
        //虚拟供应商订单是否生成转采订单
        if (!CollectionUtils.isEmpty(virtualOrganizationDtoList)) {
            //匹配虚拟供应商的订单商品
            List<String> virtualVendorOrgIds = virtualOrganizationDtoList.stream().map(OrganizationDto::getId).collect(Collectors.toList());
            List<String> virtualVendorGoodsIds = new ArrayList<>();
            for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {
                if (null != vendorOrderGoods.get("vendor_organization_id")) {
                    List<SelectorFormat> selectorFormats = JsonParseObject.parseObject(JSON.toJSONString(vendorOrderGoods.get("vendor_organization_id")), SelectorFormat.class);
                    if (!CollectionUtils.isEmpty(selectorFormats) && virtualVendorOrgIds.contains(vendorOrgIds.add(selectorFormats.get(0).getId()))){
                        virtualVendorGoodsIds.add(String.valueOf(vendorOrderGoods.get("id")));
                    }
                }
            }

            //根据订单商品获取是否生成转采订单，如果未生成则抛出异常
            List<String> cloudDeliverGoods = this.getCloudDeliverGoods(virtualVendorGoodsIds);
            Assert.isTrue(!CollectionUtils.isEmpty(cloudDeliverGoods), "商品编号：" + cloudDeliverGoods + "，未创建转采采购订单，无法发货");

        }

        // todo 非平台发货验证商品是否可操作 操作权限部分
        //非平台发货验证商品是否可操作
        if (!PlatformConst.PLATFORM_ORGANIZATION_IDS.contains(sessionUser.getCurrentOrgID())) {
            List<OrganizationDto> operateOrgGroup = OrgUtils.getOrgListByOrgId(sessionUser.getCurrentOrgID());
            Assert.isTrue(!CollectionUtils.isEmpty(operateOrgGroup), " 未找到当前用户的组织数据！ ");

            List<String> operateOrgGroupIds = operateOrgGroup.stream().map(e -> e.getId()).collect(Collectors.toList());
            for (String vendorOrgId : vendorGoodsInfo.keySet()) {
                Assert.isTrue(operateOrgGroupIds.contains(vendorOrgId),"无权限操，订单商品编号【" + vendorGoodsInfo.get(vendorOrgId) + "】");
            }
        }

        //获取可发货数量
        Map<String, BigDecimal> deliverableQuantityMap = this.getDeliverableQuantity(vendorOrderGoodsList);

        //未接单直接发货时自动触发接单，根据接单人判断是否接单
        // 接单人 order_taker_id
        List<String> needConfirmVendorOrderIds = vendorOrderGoodsList.stream().filter(e ->{
            Map<String, Object> vendorOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*").in("id", e.get("order_vendor_id")).queryForMap();
            Assert.notNull(vendorOrder,"未找到供应商订单信息！！！");
            return null == vendorOrder.get("order_taker_id") || StringUtils.isBlank(String.valueOf(vendorOrder.get("order_taker_id")));
        }).map(e -> String.valueOf(e.get("order_vendor_id"))).distinct().collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(needConfirmVendorOrderIds)) {
            orderService.orderTaking(needConfirmVendorOrderIds);
        }

        List<String> traceIds = new ArrayList<>();

        for (OrderDeliverVO orderDeliverVO : orderDeliverVOS) {
            Map<String, Object> map = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*").eq("id", orderDeliverVO.getOrderGoodsId()).queryForMap();
            OrderTraceDto orderTraces = new OrderTraceDto();
            orderTraces.setOrderVendorGoodsIds(Collections.singletonList(orderDeliverVO.getOrderGoodsId()));
            orderTraces.setOrderVendorId(map == null?null:map.get("order_vendor_id").toString());
            orderTraces.setQuantitys(Collections.singletonList(orderDeliverVO.getNum()));
            orderTraces.setFreight(orderDeliverVO.getFreight());
            orderTraces.setLogistics(orderDeliverVO.getLogistics());
            orderTraces.setWaybill(orderDeliverVO.getWaybill());
            orderTraces.setWaybills(Collections.singletonList(orderDeliverVO.getWaybill()));
            orderTraces.setArrivalTime(orderDeliverVO.getArrivalTime().toString());
            SingleResponse<BO> singleResponse = orderService.vendorDeliveryLogistics(orderTraces);
            if (singleResponse.isSuccess()) {
                traceIds.add(singleResponse.getData().getBizObjectId());
            }
        }


//        UserDto userDto = sessionUser.get();
//
//        List<Map<String, Object>> traceList = new ArrayList<>();
//        List<String> customerGoodsIds = new ArrayList<>();
//        List<String> updateCustomerGoodsIds = new ArrayList<>();
//        List<String> updateVendorGoodsIds = new ArrayList<>();
//
//        //todo 这里有个问题 老数据订单商品表是共用的，那么收货，如果要拆分，如何定位到客户订单商品 id
//        orderDeliverVOS.stream().collect(Collectors.groupingBy(OrderDeliverVO::getOrderGoodsId)).forEach( (orderGoodsId, delivers)->{
//
//            Map<String, Object> orderVendorGoods = vendorOrderGoodsList.stream().filter(t -> String.valueOf(t.get("id")).equals(orderGoodsId)).findFirst().orElse(null);
//
//            Map<String, Object> orderCustomerGoods = orderService.getOrderGoods(null, String.valueOf(orderVendorGoods.get("id")));
//            Assert.isTrue(orderCustomerGoods != null," 未找到客户订单商品数据 ！");
//            customerGoodsIds.add((String) orderCustomerGoods.get("id"));
//            //Map<String, Object> orderCustomer = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").eq("id", orderVendorGoods.get("order_customer_id")).queryForMap();
//            //Map<String, Object> orderVendor = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*").eq("id", orderVendorGoods.get("order_vendor_id")).queryForMap();
//            //已发货数量
//            BigDecimal quantityShipped = BigDecimalUtils.integerToBigDecimal(orderVendorGoods.get("quantity_shipped")));
//
//            Assert.isTrue(!OrderGoodsStatusEnum.UpcomingDelivery.name().equals(String.valueOf(orderVendorGoods.get("order_vendor_goods_status"))) ||
//                    quantityShipped.compareTo(BigDecimal.ZERO) != 1 ,"商品" + orderVendorGoods.get("id") + "状态不是出库中！");
//
//            //下单人
//            if (null != orderVendorGoods.get("place_order_user_id") && StringUtils.isNotBlank(String.valueOf(orderVendorGoods.get("place_order_user_id")))) {
//                List<SelectorFormat> selectorFormats = JsonParseObject.parseObject((String) (orderVendorGoods.get("place_order_user_id")), SelectorFormat.class);
//            }
//
//            //由于一个订单商品可能同时多次发货，产生多个发货单，所以需要累计后验证发货数量
//            BigDecimal verifyNum = BigDecimal.ZERO;
//            for (OrderDeliverVO deliver : delivers) {
//                Map<String, Object> trace = new HashMap<>();
//                trace.put("type", TraceTypeEnum.ShippingLogistics.toString());
//                trace.put("order_vendor_goods_id", orderVendorGoods.get("id"));
//                trace.put("sender_id", sessionUser.getUserFormat());
//                trace.put("recipient_id", sessionUser.getUserFormat());
//                trace.put("logistics", deliver.getLogistics());
//                trace.put("freight", deliver.getFreight());
//                trace.put("quantity", deliver.getNum());
//                trace.put("waybill", deliver.getWaybill());
//                trace.put("arrival_time", deliver.getArrivalTime());
//
//                trace.put("order_customer_goods_id", orderCustomerGoods.get("id"));
//                trace.put("order_customer_id", orderVendorGoods.get("order_customer_id"));
//                trace.put("order_vendor_id", orderVendorGoods.get("order_vendor_id"));
//                //其他字段赋值
//                Object customer_organization_id = orderCustomerGoods.get("customer_organization_id");
//                trace.put("customer_organization_id", Objects.isNull(customer_organization_id) ? null : JSON.parseObject((String) customer_organization_id, SelectorFormat.class));
//                trace.put("customer_organization_name", orderCustomerGoods.get("customer_organization_name"));
//                Object vendor_organization_id = orderCustomerGoods.get("customer_organization_id");
//                trace.put("vendor_organization_id", Objects.isNull(vendor_organization_id) ? null : JSON.parseObject((String) vendor_organization_id, SelectorFormat.class));
//                SelectorFormat send = userDto.createSelectorFormat();
//                trace.put("sender_id", send);
//                trace.put("sender_fullname", send.getName());
//                Object place_order_user_id = orderCustomerGoods.get("place_order_user_id");
//                trace.put("recipient_id", Objects.isNull(place_order_user_id) ? null : JSON.parseObject((String) place_order_user_id, SelectorFormat.class));
//                trace.put("recipient_fullname", orderCustomerGoods.get("place_order_fullname"));
//                trace.put("quantity_received", BigDecimalUtils.round(BigDecimalUtils.isNull(orderCustomerGoods.get("quantity_received")), 6));
//                trace.put("name", orderCustomerGoods.get("name"));
//                trace.put("quantity_unit", BigDecimalUtils.round(BigDecimalUtils.isNull(trace.get("quantity")), 0) + "/" + orderCustomerGoods.get("unit"));
//
//                traceList.add(trace);
//                verifyNum = deliver.getNum().add(verifyNum);
//            }
//
//            BigDecimal deliverableNum = deliverableQuantityMap.get(orderGoodsId);
//            Assert.isTrue(verifyNum.compareTo(deliverableNum) <= 1,"订单商品编号【" + orderGoodsId + "】发货数量【" + verifyNum + "】不可大于可发货数量【" + deliverableNum + "】");
//
//            BigDecimal afterDeliverableNum = deliverableNum.subtract(verifyNum);
//
//            if (afterDeliverableNum.compareTo(BigDecimal.ZERO) <= 1) {
//                updateCustomerGoodsIds.add((String) orderCustomerGoods.get("id"));
//                updateVendorGoodsIds .add((String) orderVendorGoods.get("id"));
//            }
//        });
//
//        //保存物流信息
//        // 返回需要id集合
//        List<String> traceIds = new ArrayList<>();
//        for (Map<String, Object> traceData : traceList) {
//            SingleResponse<BO> bo = BoServiceUtils.createBo(ModelConst.T_ORDER_TRACE, Collections.singletonList(traceData));
//            if (bo.isSuccess()) traceIds.add(bo.getData().getBizObjectId());
//        }
//
//        //更新订单商品数据表
//        if (!CollectionUtils.isEmpty(updateCustomerGoodsIds)) {
//            List<Map<String, Object>> updateCustomerList = new ArrayList();
//            updateCustomerGoodsIds.stream().forEach(e->{
//                Map<String, Object> updateCustomerParam = new HashMap<>();
//                updateCustomerParam.put("id",e);
//                updateCustomerParam.put("order_customer_goods_status",OrderGoodsStatusEnum.DoneDelivery.name());
//                updateCustomerList.add(updateCustomerParam);
//
//            });
//            BoServiceUtils.updateMainBo(ModelConst.T_ORDER_CUSTOMER_GOODS,updateCustomerList);
//        }
//
//        if (!CollectionUtils.isEmpty(updateVendorGoodsIds)) {
//            List<Map<String, Object>> updateVendorList = new ArrayList();
//            updateVendorGoodsIds.stream().forEach(e->{
//
//                Map<String, Object> updateVendorParam = new HashMap<>();
//                updateVendorParam.put("id",e);
//                updateVendorParam.put("order_vendor_goods_status",OrderGoodsStatusEnum.DoneDelivery.name());
//                updateVendorList.add(updateVendorParam);
//
//            });
//            BoServiceUtils.updateMainBo(ModelConst.T_ORDER_VENDOR_GOODS,updateVendorList);
//        }
//
//        // 回写转采和财务订单商品状态
//        orderService.updateTransferOrderStatus(customerGoodsIds);
//
//        List<Map<String, Object>> writeBackParams = new ArrayList<>();
//        for (Map<String, Object> vendorOrderGoods1 : vendorOrderGoodsList) {
//            Map<String, Object> orderCustomerGoods = orderService.getOrderGoods(null, String.valueOf(vendorOrderGoods1.get("id")));
//            Map<String, Object> writeBackParam = new HashMap<>();
//            writeBackParam.put("orderGoodsId", orderCustomerGoods.get("id"));
//            writeBackParam.put("orderGoodsStatus", OrderGoodsStatusEnum.DoneDelivery.name());
//            writeBackParams.add(writeBackParam);
//        }
//        dockFinanceService.writeBackTradesOrder(writeBackParams);

        return TempOrderReceipt.builder().traceIds(traceIds).vendorOrderIds(new HashSet<>(needConfirmVendorOrderIds)).build();
    }



    /**
     * 获取表名称
     *
     * @param schemaCode
     * @return
     */
    public String getTableName(String schemaCode) {
        return tableHelper.getTableName(schemaCode);
    }
}
